/*
 * CopyRight (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
 */
package com.huawei.bdsolution.loadsmetric.service.impl;

import com.huawei.bdsolution.loadsmetric.dto.FixedSizeRingBuffer;
import com.huawei.bdsolution.loadsmetric.dto.LoadsRecordAverage;
import com.huawei.bdsolution.loadsmetric.dto.NodeLogicalResource;
import com.huawei.bdsolution.loadsmetric.dto.SortReport;
import com.huawei.bdsolution.loadsmetric.entity.LoadsRecords;
import com.huawei.bdsolution.loadsmetric.service.SortReportService;
import com.huawei.bdsolution.loadsmetric.util.MultiLoadResourceUsageSortPolicy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

@Service
public class SortReportServiceImpl implements SortReportService {

    @Autowired
    MultiLoadResourceUsageSortPolicy multiLoadResourceUsageSortPolicy;

    private List<LoadsRecordAverage> loadsRecordAverageList;

    public List<LoadsRecordAverage> getLoadsRecordAverageList() {
        return loadsRecordAverageList;
    }

    @Override
    public SortReport sortNodesByUsagesWithLogicalFromCache(
            Map<String, FixedSizeRingBuffer<LoadsRecords>> loadsRecordsCacheMap,
            Map<String, NodeLogicalResource> nodeLogicalResourceMap) {
        loadsRecordAverageList = multiLoadResourceUsageSortPolicy.calculateAverage(loadsRecordsCacheMap);
        multiLoadResourceUsageSortPolicy.calculateWeight(loadsRecordAverageList);
        addLogicalResource(nodeLogicalResourceMap);
        return multiLoadResourceUsageSortPolicy.sortNodesWithCustomSortOrder(loadsRecordAverageList);
    }

    private void addLogicalResource(Map<String, NodeLogicalResource> nodeLogicalResourceMap){
        if (null == loadsRecordAverageList) {
            return;
        }
        for (LoadsRecordAverage loadsRecordAverage : loadsRecordAverageList) {
            NodeLogicalResource logicalResource = nodeLogicalResourceMap.get(loadsRecordAverage.getHostName());
            if (logicalResource == null) {
                continue;
            }
            loadsRecordAverage.setMemUsageLevel(logicalResource.getMemUsageLevel());
            loadsRecordAverage.setVcoresUsageLevel(logicalResource.getVcoresUsageLevel());
        }
    }

    /**
     * get every host's loads metric usage info for Prometheus
     *
     * @return loads metric usage info
     */
    @Override
    public String getRecordsByCurrTimeForPrometheus() {
        StringBuilder res = new StringBuilder();
        res.append("# HELP loads metrics detail:curr usage for host\n");
        res.append("# TYPE loads_metrics_detail gauge\n");
        if (getLoadsRecordAverageList() != null) {
            int orderSeq = 0;
            for (LoadsRecordAverage loadsRecords : getLoadsRecordAverageList()) {
                res.append(String.format("loads_metrics_detail{host=\"%s\",type=\"%s\"} %s\n",
                        loadsRecords.getHostName(), "cpu", loadsRecords.getAvgCpuUsage()));
                res.append(String.format("loads_metrics_detail{host=\"%s\",type=\"%s\"} %s\n",
                        loadsRecords.getHostName(), "mem", loadsRecords.getAvgMemUsage()));
                res.append(String.format("loads_metrics_detail{host=\"%s\",type=\"%s\"} %s\n",
                        loadsRecords.getHostName(), "disk_io", loadsRecords.getAvgDiskIoUsage()));
                res.append(String.format("loads_metrics_detail{host=\"%s\",type=\"%s\"} %s\n",
                        loadsRecords.getHostName(), "net_io", loadsRecords.getAvgNetIoUsage()));
                for (String sortOrderName : multiLoadResourceUsageSortPolicy.getCustomSortOrderNamesArray()) {
                    res.append(String.format("loads_metrics_detail{host=\"%s\",type=\"%s\"} %s\n",
                            loadsRecords.getHostName(), sortOrderName,
                            loadsRecords.getSortInfoOriginalValue(sortOrderName)));
                }
                res.append(String.format("loads_metrics_detail{host=\"%s\",type=\"%s\"} %s\n",
                        loadsRecords.getHostName(), "overload_type", loadsRecords.getOverLoadType()));
                res.append(String.format("loads_metrics_detail{host=\"%s\",type=\"%s\"} %s\n",
                        loadsRecords.getHostName(), "order_seq", orderSeq++));
            }
        }
        res.append("# EOF");
        return res.toString();
    }
}
